package
{
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.text.AntiAliasType;
	import flash.text.Font;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	
	import flashx.textLayout.formats.FormatValue;
	import flashx.textLayout.formats.TextAlign;

	public class MyGraphics
	{
		protected var backBuffer:BitmapData;
		protected var textFormat:TextFormat = new TextFormat;
		protected var colorTransform:ColorTransform;
		protected var textField:TextField = new TextField();
		public function MyGraphics(width:int, height:int)
		{
			backBuffer = new BitmapData(width, height, false);
		}
		public function Width():int
		{
			return backBuffer.width;
		}
		public function Height():int
		{
			return backBuffer.height;
		}
		public function FillRect(x:Number, y:Number, width:Number, height:Number, color:uint):void
		{
			var a:Number = (color >> 24)/255;
			var r:int = (color >> 16) & 0x000000FF;
			var g:int = (color >> 8) & 0x000000FF;
			var b:int = color & 0x000000FF;
			var ia:Number = 1 - a;
			backBuffer.colorTransform(new Rectangle(x,y,width,height)
				, new ColorTransform(ia,ia,ia,1,r*a,g*a,b*a));
			//backBuffer.fillRect(new Rectangle(x,y,width,height), color);
		}
		public function DrawRect(x:Number, y:Number, width:Number, height:Number, color:uint, thickness:Number):void
		{
			var shape:Shape = new Shape();
			shape.graphics.lineStyle(thickness,color);
			shape.graphics.drawRect(x,y,width,height);
			backBuffer.draw(shape);
		}
		public function Clear(color:uint):void
		{
			backBuffer.fillRect(new Rectangle(0,0,backBuffer.width,backBuffer.height), color);
		}
		public function DrawCircle(x:Number, y:Number, radius:Number, color:uint):void
		{
			var shape:Shape = new Shape();
			shape.graphics.beginFill(color);
			shape.graphics.drawCircle(x,y,radius);
			shape.graphics.endFill();
			backBuffer.draw(shape);
		}
		public function DrawBitmapData(bm:BitmapData, x:Number, y:Number):void
		{
			var matrix:Matrix = new Matrix();
			matrix.translate(x, y);
			backBuffer.draw(bm,matrix,colorTransform);
		}
		public function DrawBitmapDataClip(bm:BitmapData, x:int, y:int, xclip:int, yclip:int, width:int, height:int):void
		{
			var matrix:Matrix = new Matrix();
			matrix.translate(x - xclip, y - yclip);
			var rc:Rectangle = new Rectangle(x,y,width,height);
			backBuffer.draw(bm,matrix,colorTransform,null,rc);
		}
		public function DrawBitmapDataRotate(bm:BitmapData, x:Number, y:Number, a:Number):void
		{
			var matrix:Matrix = new Matrix();
			matrix.translate(-bm.width/2, -bm.height/2);
			matrix.rotate(a);
			matrix.translate(x + bm.width/2, y + bm.height/2);
			backBuffer.draw(bm,matrix,colorTransform);
		}
		public function DrawMovieClip(mv:MovieClip, x:Number, y:Number):void
		{
			var matrix:Matrix = new Matrix();
			matrix.translate(x, y);
			backBuffer.draw(mv,matrix, colorTransform);
		}
		public function DrawMovieClipRotate(mv:MovieClip, x:Number, y:Number, a:Number):void
		{
			var matrix:Matrix = new Matrix();
			matrix.translate(-mv.width/2, -mv.height/2);
			matrix.rotate(a);
			matrix.translate(x + mv.width/2, y + mv.height/2);
			backBuffer.draw(mv,matrix, colorTransform);
		}
		public function DrawLine(x1:Number, y1:Number, x2:Number, y2:Number, color:uint = 0xFF000000, thickness:Number = 1, alpha:Number = 1.0):void
		{
			var shape:Shape = new Shape();
			shape.graphics.lineStyle(thickness, color,alpha);
			shape.graphics.moveTo(x1,y1);
			shape.graphics.lineTo(x2,y2);
			backBuffer.draw(shape);
		}
		public function Flip(g:Graphics):void
		{
			g.clear();
			g.beginBitmapFill(backBuffer);
			g.drawRect(0,0,backBuffer.width,backBuffer.height);
			g.endFill();
		}
		public function DrawString(s:String, x:Number, y:Number, color:uint):void
		{
			//var tx:TextField = new TextField();
			textField.width = Game.GetWidth();
			textField.height = Game.GetHeight();
			textField.antiAliasType = AntiAliasType.ADVANCED;
			textField.text = s;
			textField.textColor = color;
			//tx.background = false;
			textField.backgroundColor = color;
			textField.setTextFormat(textFormat);
			var matrix:Matrix = new Matrix();
			if(textFormat.align == TextFormatAlign.LEFT)
			{
				matrix.translate(x, y);
			}
			else if(textFormat.align == TextFormatAlign.CENTER)
			{
				matrix.translate(x - textField.width/2, y);
			}
			else if(textFormat.align == TextFormatAlign.RIGHT)
			{
				matrix.translate(x - textField.width, y);
			}
			backBuffer.draw(textField, matrix, colorTransform);
		}
		public function SetTextSize(size:Number):void
		{
			textFormat.size = size;
		}
		public function SetTextAlign(align:String):void
		{
			textFormat.align = align;
		}
		public function SetFont(fontName:String):void
		{
			textFormat.font = fontName;
			textField.embedFonts = true;
		}
		public function SetColorTransform(cT:ColorTransform):void
		{
			colorTransform  = cT;
		}
		public function ResetColorTransform():void
		{
			colorTransform = null;
		}
		public function CopyBackBuffer():BitmapData
		{
			return backBuffer.clone();
		}
		public function SetFontEmbed(font:Font):void
		{
			textFormat.font = font.fontName;
			textField.embedFonts = true;
		}
	}
}